﻿using PivotData;
using PivotIO.XML;
using System.Linq;
using System.Net;
using System.Web.Http;

namespace PivotWebsite.Controllers
{
    /// <summary>
    /// Return the facet properties, or set them.
    /// </summary>
    public class FacetCategoriesController : ApiController
    {
        /// <summary>
        /// Get a list of all catagories.
        /// </summary>
        /// <param name="cId">The collection id to get the facets for.</param>
        /// <returns></returns>
        public FacetCategory[] Get(int cId)
        {
            if (!CollectionInfoIO.Exists(cId))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }
            var explicitFacets = FacetCategoryIO.LoadAllFacets(cId);

            // And then there are facets that no one has bothered to set, that will aquire default
            // values. We should return those as well.

            var defaultFacts = from f in ImageInfoIO.GetDefaultFacetNames(cId).Except(explicitFacets.Select(f => f.Name))
                               select new FacetCategory() { Name = f };
            return explicitFacets.Concat(defaultFacts).ToArray();
        }

        /// <summary>
        /// Add some facet categories to the list that we already know about
        /// </summary>
        /// <param name="cId"></param>
        /// <param name="facets"></param>
        public void Put(int cId, [FromBody] FacetCategory[] facets)
        {
            if (!CollectionInfoIO.Exists(cId) || facets == null)
                throw new HttpResponseException(HttpStatusCode.BadRequest);
            if (facets.Any(f => string.IsNullOrWhiteSpace(f.Name)))
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            // Check that all the number specifiers are good!
            decimal d = (decimal)5.2331;
            foreach (var item in facets.Select(f => f.NumberFormat))
            {
                try
                {
                    var r = d.ToString(item);
                    if (r == item)
                        throw new HttpResponseException(HttpStatusCode.BadRequest);
                }
                catch
                {
                    throw new HttpResponseException(HttpStatusCode.BadRequest);
                }
            }

            var fs = FacetCategoryIO.LoadAllFacets(cId);

            var allNewNames = facets.Select(f => f.Name).ToArray();
            var fsClean = from f in fs
                          where allNewNames.All(alN => f.Name != alN)
                          select f;
            var fsNew = fsClean.Concat(facets);
            FacetCategoryIO.SaveAllFacets(cId, fsNew.ToArray());
        }

        /// <summary>
        /// Delete a facet specification. If it already exists for some sub-set of images, then
        /// it will remain.
        /// </summary>
        /// <param name="cId"></param>
        public void Delete(int cId)
        {
            if (!CollectionInfoIO.Exists(cId))
                throw new HttpResponseException(HttpStatusCode.BadRequest);

            FacetCategoryIO.SaveAllFacets(cId, new FacetCategory[0]);
        }

        /// <summary>
        /// Delete a particular facet.
        /// </summary>
        /// <param name="cId"></param>
        /// <param name="fname"></param>
        public void Delete(int cId, string fname)
        {
            var fcs = FacetCategoryIO.LoadAllFacets(cId);
            if (!fcs.Any(f => f.Name == fname))
                if (!ImageInfoIO.GetDefaultFacetNames(cId).Any(s => s == fname))
                    throw new HttpResponseException(HttpStatusCode.BadRequest);

            var goodFcs = fcs.Where(f => f.Name != fname);

            FacetCategoryIO.SaveAllFacets(cId, goodFcs.ToArray());
        }
    }
}
